package com.mate.cloud.redisnetworkmodel.BIO;


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * NIO 实现简单的 TCP 服务器
 * <p>
 * - 假设银行只有 1 个窗口（1 个线程），每个客户（1 个连接）办理业务（I/O 操作）时，窗口会被独占：
 * <p>
 * - 客户 A 办理存款（I/O 操作），期间窗口不能处理其他客户（线程阻塞）；
 * - 只有客户 A 办完（I/O 完成），客户 B 才能开始办理。
 *
 * @author: MI
 * @email: 448341911@qq.com
 * @createTime: 2025/9/3 13:52
 * @updateUser: MI
 * @updateTime: 2025/9/3 13:52
 * @updateRemark: 修改内容
 * @version: 1.0
 */
public class BioTcpServer {
    public static void main(String[] args) throws IOException {
        // 1. 创建 ServerSocket，监听 8080 端口
        ServerSocket serverSocket = new ServerSocket(8080);
        System.out.println("BIO 服务器启动，监听 8080 端口...");

        while (true) {
            // 2. 阻塞等待客户端连接（accept() 方法阻塞）
            Socket clientSocket = serverSocket.accept();
            System.out.println("新客户端连接：" + clientSocket.getInetAddress());

            // 3. 每来一个连接，新建一个线程处理（关键：一个连接一个线程）
            new Thread(() -> {
                try {
                    // 获取输入流（读取客户端数据）、输出流（向客户端写响应）
                    InputStream in = clientSocket.getInputStream();
                    OutputStream out = clientSocket.getOutputStream();
                    byte[] buffer = new byte[1024];
                    while (true) {
                        // 4. 阻塞读取客户端数据（read() 方法阻塞，没有数据时线程暂停）
                        int len = in.read(buffer);
                        if (len == -1) break; // 客户端关闭连接，退出循环

                        // 处理数据（这里简单打印并返回相同内容）
                        String clientMsg = new String(buffer, 0, len);
                        System.out.println("收到客户端消息：" + clientMsg);

                        // 向客户端返回响应
                        String response = "服务器已收到：" + clientMsg;
                        out.write(response.getBytes());
                        out.flush(); // 强制刷新缓冲区，确保数据发送
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        clientSocket.close(); // 关闭客户端连接
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    System.out.println("客户端连接关闭");
                }
            }).start();
        }
    }

}
